package com.hzhc.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.hzhc.dto.UserDto;
import com.hzhc.entity.UserMember;
import com.hzhc.enumBean.LoginUserType;
import com.hzhc.vo.SysUserVo;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * @ClassName: TokenUtil
 * @Description:
 * @version 1.0
 * @author: duanhm
 * @Date: 2022/01/29 21:43:22
 *
 */
public class TokenUtil {
	private static final long WX_EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000;// token到期时间7*24小时

	private static final long EXPIRE_TIME = 300 * 60 * 1000;
	private static final String TOKEN_SECRET = "tokenHC"; // TOKEN盐
	private static final String ISSUER = "HZHCXX.COM";// 发行人


	/**
	 * 签名生成
	 *
	 * @param vo
	 * @return
	 */
	public static String sign(SysUserVo vo) {
		String token = null;
		try {
			Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
			token = JWT.create().withIssuer(ISSUER)
					.withClaim("userType", LoginUserType.USER.getCode())
					.withClaim("username", vo.getRealname())
					.withClaim("userId", vo.getId())
					.withClaim("loginname", vo.getLoginname())
					.withClaim("orgId", vo.getOrgId())
					.withClaim("accountPermission", vo.getAccountPermission())
					.withExpiresAt(expiresAt)
					// 使用了HMAC256加密算法。
					.sign(Algorithm.HMAC256(TOKEN_SECRET));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return token;
	}

	/**
	 * 签名生成 signMember
	 *
	 * @param vo
	 * @return
	 */
	public static String signMemberToken(UserMember vo) {
		String token = null;
		try {
			Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
			token = JWT.create().withIssuer(ISSUER)
				.withClaim("userType", LoginUserType.MEMBER.getCode())
				.withClaim("username",  vo.getRealName())
				.withClaim("memberId", vo.getId())
				.withClaim("companyId", vo.getCompanyId())
				.withClaim("companyName", vo.getCompanyName())
				.withClaim("loginname", vo.getUsername())
				.withExpiresAt(expiresAt)
				// 使用了HMAC256加密算法。
				.sign(Algorithm.HMAC256(TOKEN_SECRET));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return token;
	}


	/**
	 * 签名验证
	 *
	 * @param token
	 * @return
	 */
	public static boolean verify(String token) {
		try {
			JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer(ISSUER).build();
			DecodedJWT jwt = verifier.verify(token);
			System.out.println("认证通过：");
			System.out.println("issuer: " + jwt.getIssuer());
			System.out.println("username: " + jwt.getClaim("username").asString());
			System.out.println("userType: " + jwt.getClaim("userType").asString());
			System.out.println("userId: " + jwt.getClaim("userId").asString());
			System.out.println("过期时间：      " + jwt.getExpiresAt());
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			// token 校验失败, 抛出Token验证非法异常
			return false;
		}
	}
	/**
	 * 根据Token获取user
	 *
	 * @param request
	 * @return user_id
	 */
	public static UserDto getUserMember(HttpServletRequest request) {
		try {
			String token=request.getHeader("token");
			JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer(ISSUER).build();
			DecodedJWT jwt = verifier.verify(token);
			UserDto userDto = new UserDto();
			userDto.setId(jwt.getClaim("memberId").asLong());
			userDto.setLoginname(jwt.getClaim("loginname").asString());
			userDto.setRealname(jwt.getClaim("username").asString());
			userDto.setUserType(jwt.getClaim("userType").asString());
			userDto.setCompanyId(jwt.getClaim("companyId").asLong());
			userDto.setCompanyName(jwt.getClaim("companyName").asString());
			userDto.setAppToken(jwt.getClaim("appToken").asString());
			userDto.setAccessToken(jwt.getClaim("accessToken").asString());
			return userDto;
		} catch (Exception e) {
			e.printStackTrace();
			// token 校验失败, 抛出Token验证非法异常
			return null;
		}
	}


	/**
	 * 根据Token获取user
	 *
	 * @param request
	 * @return user_id
	 */
	public static UserDto getUser(HttpServletRequest request) {
		try {
			String token=request.getHeader("token");
			JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer(ISSUER).build();
			DecodedJWT jwt = verifier.verify(token);
			UserDto userDto = new UserDto();
			userDto.setId(jwt.getClaim("userId").asLong());
			userDto.setLoginname(jwt.getClaim("loginname").asString());
			userDto.setRealname(jwt.getClaim("username").asString());
			userDto.setUserType(jwt.getClaim("userType").asString());
			userDto.setCompanyId(jwt.getClaim("companyId").asLong());
			userDto.setCompanyName(jwt.getClaim("companyName").asString());
			return userDto;
		} catch (Exception e) {
			e.printStackTrace();
			// token 校验失败, 抛出Token验证非法异常
			return null;
	}
	}

	/**
	 * 根据Token获取user_id
	 *
	 * @param request
	 * @return user_id
	 */
	public static Long getUserID(HttpServletRequest request) {
		String token=request.getHeader("token");
		JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer(ISSUER).build();
		DecodedJWT jwt = verifier.verify(token);
        return jwt.getClaim("userId").asLong()==null?jwt.getClaim("memberId").asLong():jwt.getClaim("userId").asLong();
    }

	/**
	 **刷新签名
	 *
	 * @param token
	 * @return
	 */
	public static String refreshToken(String token,String userType) {
		String retToken = null;
		try {
		JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer(ISSUER).build();
		DecodedJWT jwt = verifier.verify(token);
		String username = jwt.getClaim("username").asString();
		Long userId = jwt.getClaim("userId").asLong();
		Long memberId = jwt.getClaim("memberId").asLong();
		String loginname = jwt.getClaim("loginname").asString();
		Long companyId = jwt.getClaim("companyId").asLong();
		String companyName = jwt.getClaim("companyName").asString();
		Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
		retToken = JWT.create().withIssuer(ISSUER)
					.withClaim("username", username)
					.withClaim("userType", userType)
					.withClaim("userId", userId)
					.withClaim("memberId", memberId)//memberId
					.withClaim("loginname", loginname)
					.withClaim("companyId", companyId)
					.withClaim("companyName", companyName)
					.withExpiresAt(expiresAt)
					// 使用了HMAC256加密算法。
					.sign(Algorithm.HMAC256(TOKEN_SECRET));
			return retToken;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
